

                     L                ZZZZZZ         RRRRR           SSSSS
                     L                    Z          R    R         S
                     L          aaa      Z      aaa  R    R  u   u  S
                     L            a     Z         a  RRRRR   u   u  SSSSS
               XX    L         aaaa    Z       aaaa  R    R  u   u       S
              XXXX   L        a   a   Z       a   a  R    R  u   u       S
             XXXXXX  LLLLLLL  aaaaa  ZZZZZZZ  aaaaa  R    R  uuuuu  SSSSSS
             XXXXXX       
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
             XXXXXX
             XXXXXX
              XXXX        proudly presents his 12.Cracking Tutorial (29.04.1999)
               XX                    Latigo's Javascript Reverse Me 3.0

I.   Tools you need for my tutorial
II.  The Cracking
III. BTW

I.   Tools you need for my tutorial
     Netscape X.X (Javascript enabled)
     Latigo's Reverse Me (get it at http://www.idca.com/~thesandman in the Javascript section)


II.  Cracking:
     Until I found this one I always thought Javascript CrackMes are boring and uninteresting
     because you are able to see the code and all JS CrackMes I tried before were pretty easy
     to solve. Forgive me for this sucking attitude now I changed it ;-). Latigo's Reverse 
     Me was a damn hard one and it took me quite a few hours. Changing the script that you always
     come to the "Good" page is pretty easy, but finding a correct "serial" was really hard. Now
     I can say that it was so hard to get a correct serial was the reason that there are nearly
     infinite solutions (nice paradoxon, isn't it ;-). You'll see later, what I mean. Let's 
     start cracking.

     I'll present you the script of the CrackMe.

     <script>                                            // script starts
     var searcho = location.search;                      // Look (1) below before you read on
     firstPart = "";                                     // variable firstPart is initialized
     secondPart = "";                                    // variable secondPart is initialized

separar(searcho);                                        // calls function separar with parameter

function separar(string)                                 // function separar is defined
	{
	string = string.substring(1,string.length)       // string = is the one specified in (1)
	ampersand = string.indexOf("&");                 // where's a "&" in the string
	firstPart = string.substring(0,ampersand);       // firstPart=The string until the "&"
                                                         // appears (2)
	secondPart = string.substring(ampersand + 1,string.length); // part behind the "&" see(2)
	}                                                // end of function
	
function encode(string)                                  // function encode is defined
	{
	var producto = 0;                                // variable producto=0
	for (i = 0; i < string.length; i++)              // for each char of the parameter string
		{
		producto +=(string.charCodeAt(i) ^i) * 8;// producto = producto + ((char XOR 
                                                         // position of letter) * 8)  see (3)
		}
	return (producto);	                         //gives back the serial that is compared
	}

		
if (searcho.length < 1)                                  // if there's no string behind the "?"
	{
location.href = "incorrect.html"                         // Loser
	}

function loser()                                         // This is the loser-function
	{
	alert('Still uncracked!');
	location.href="incorrect.html";
	}
function winner()                                        // This is the winner-function
	{
	alert('Good boy! now tell me how its done!');
	location.href="correct.html"
	}
		
//discrimination
var igual = firstPart.indexOf("=");                 // position of a "=" in the 1st string ? (4)
var igual2 = secondPart.indexOf("=");               // position of a "=" in the 2nd string ? (4)
if (encode(firstPart.substring(0,igual)) != 6608) loser(); (5)
else if (encode(firstPart.substring(igual + 1,firstPart.length)) != 9712) loser(); (6)
else if (encode(secondPart.substring(0,igual2)) != 6696)	loser(); (6)
else if (encode(secondPart.substring(igual2 + 1,secondPart.length)) != 9832) loser(); (8)

else winner();  // if you are through all checks successfully then you have solved this one


</script>


     (1) As I found in a HTML reference the JS function location.search checks, if there's a 
     string added to the URL in the input field. The URL and the string are connected by a "?".
     An example for our ReverseMe is reverse3.html?Hello. This string behind the URL is the
     one which is important for the serial.
 
     (2) Now we know that the string must look something like reverse3.html?Hello&Iamhere

     (3) For each letter of the parameter string producto is added ((letter XOR position of the
     letter) * 8) You have to be careful here: The first letter is producto[0], the second
     producto[1] and so on.

     (4) Now (and because of the next few lines) we know that there must be a "=" in the first
     string and in the second string. You will later see, that it musn't be at the beginning or
     at the end of the strings but somewhere in the middle. Example: reverse3.html?A=B&C=D

     (5) The first part of the first string (A in the previuos example) is given as parameter to
     the encrypt function. This one returns a value that is compared with 6608. If they are not
     the same then you are a loser, if they are the same go for the next check.

     (6) The second part of the first string (B in the previuos example) is given as parameter to
     the encrypt function. This one returns a value that is compared with 9712. If they are not
     the same then you are a loser, if they are the same go for the next check.

     (7) The third part of the first string (C in the previuos example) is given as parameter to
     the encrypt function. This one returns a value that is compared with 6696. If they are not
     the same then you are a loser, if they are the same go for the next check.

     (8) The fourth part of the first string (D in the previuos example) is given as parameter to
     the encrypt function. This one returns a value that is compared with 9832. If they are not
     the same then you are a loser, if they are the same go for the next check.

     
     Enough source explaination, now go for the crack. Go between these to lines

     var igual2 = secondPart.indexOf("=");
     if (encode(firstPart.substring(0,igual)) != 6608) loser();

     and add 

     alert(encode(firstPart.substring(0,igual)));

     The way the string is encoded you see that it is probably best to choose chars with high
     ASCII (or in Windows correcter ANSI) values. I have chosen "z" (ASCII 122), because I don't
     "trust" higher values. They can sometimes have conflicts with whatever. OK, you know the
     structure of the "serial", so open Netscape and enter reverse3.html?zzzzz=zzzzz&zzzzz=zzzzz
     Load the site and a messagebox appears telling you the value of your first string. It is
     4896. We have to get 6608, so better add one "z". Then the msgbox says "5912". If we add
     two "z" it says "6904". So one "z" is too less and two "z" too much. Now we have know some
     mathematics (luckily only some).

     We have producto +=(string.charCodeAt(i) ^i) * 8;
     You (really should) know that the opposite of *8 is /8. There's no opposite of XOR but
     something nearly similar. 
     If   A XOR B = C 
     then A XOR C = B 
     and  B XOR C = A

     With this knowlege we can get a correct serial for the first part. We need 6608, but we only
     have 5912. That's a difference of 696. This must be divided by 8. Now we have 87. We have
     a string that consists of "zzzzzz". So the char we have to add has position 6 (remember:
     first "real" position is 0. "JS" position). With the XOR rules we know that the ASCII value
     of the missing char is 87 XOR 6 (because the missing value is XORed with the position).
     87 XOR 6 = 81. Ascii(81) = "Q". So the first part of the first string is "zzzzzzQ". Try it
     out: reverse3.html?zzzzzzQ=zzzzz&zzzzz=zzzzz. The messagebox says 6608 and we can go to
     the next calculation.
     
     The second calculation is the same as the first one (and the third and the fourth), so I
     don't think I have to explain what happens. Just look at the return value the function must
     have. But watch out: In the third step (String two / part one) there's a little problem.
     If you choose as much "z" that you are close to 6696 and divide the value by 8 and XOR it
     with CAN'TREMEMBER you get 3. You cannot write a char with ASCII(3). So take one z away and
     calculate again. (btw: Perhaps it was not third part, but somewhere this problem appears
     when you choose "z" as base)

     Now you should know why this ReverseMe has nearly infinite solutions. If you choose "!" as
     base and start with ?000000=0000000&000000=000000 you can get *really* long serials, because
     "!" is only ASCII(32).

     With my system I found a valid serial that is: 
     reverse3.html?zzzzzzQ=zzzzzzzzzy&zzzzzzd=zzzzzzzzzv

     Successfully cracked (although it was a hard one that took me several hours when I was 
     trying to find the opposite of XOR) :)

III. BTW
     Hope my tutorial was helpful for you and see you again in my next tutorial. 
     
     Greets to: Fravia+, tKC, ED!SON, Moral Insanity, The Sandman, Eternal Bliss, DaVinci and 
     all [hf] members


All Tutorials by LaZaRuS [hf]

 #|  date  |   name           |version|W32Dasm|Soft-Ice|kind of crack            |
--|--------|------------------|-------|-------|--------|-------------------------|
01|20.01.99|Jaylock           |1,0,0,1|  (X)  |   (X)  |serial#                  |
02|31.01.99|Goldwave          |4.02   |  (X)  |   (X)  |serial#,nag-screens      |
03|28.03.99|AxMan             |3.00   |  (X)  |   (X)  |serial#,remove date-limit|
  |        |                  |       |       |        |nag-screen, key generator|
04|29.03.99|C++Builder Strings|       |  (X)  |   (X)  |how to find strings in   |
  |        |                  |       |       |        |C++ Builder that are not |
  |        |                  |       |       |        |hardcoded                |
05|29.03.99|Better Protection |       |       |        |How to protect shareware |
  |        |                  |       |       |        |better against crackers  |
06|04.04.99|Start Clean       |1.2    |  (X)  |   (X)  |nag-screen/serial/keygen |
07|06.04.99|MP3 TO EXE        |1.02   |  (X)  |   (X)  |nag-screen/serial        |
08|06.04.99|HexDecCharEditor  |1.02   |  (X)  |        |make it registered       |
09|20.04.99|PowerZip          |4.51   |  (X)  |        |serial/time-check/...    |
10|24.04.99|eKH CrackMe       |1.0    |  (X)  |        |serial                   |
11|25.04.99|F-Secure          |4.02   |  (X)  |        |time limit/nag           |
12|29.04.99|Latido's JS       |3.0    |       |        |serial                   |
  |        |Reverse Me        |       |       |        |                         |
     
LaZaRuS [hf]
Visit Hellforge at http://come.to/hellforge for more tutorials and high quality cracking links.
If you want to mail me: lazarus666@gnwmail.com